// Nested if-statement description for a stopwatch

module stop_watch_if
    (
    input  wire       clk,
    input  wire       go, clr,
    output wire[3:0]  d2, d1, d0
    );

    // declaration
    localparam DVSR = 10000000;
    reg[23:0]  ms_reg;
    wire[23:0] ms_next;
    reg[3:0]   d2_reg, d1_reg, d0_reg;
    reg[3:0]   d2_next, d1_next, d0_next;
    wire       ms_tick;

    // body
    // register
    always @(posedge clk)
    begin
        ms_reg <= ms_next;
        d2_reg <= d2_next;
        d1_reg <= d1_next;
        d0_reg <= d0_next;
    end

    // next-state logic
    // 0.1 sec tick generator mod-10.000.000
    assign ms_next = (clr || (ms_reg==DVSR && go)) ? 4'b0 :
                     (go) ? ms_reg + 1 :
                            ms_reg;
    assign ms_tick = (ms_reg==DVSR) ? 1'b1 : 1'b0;

    // 3-digt bcd counter
    always @*
    begin
        // default: keep the previous value
        d0_next = d0_reg;
        d1_next = d1_reg;
        d2_next = d2_reg;
        if (clr)
            begin
                d0_next = 4'b0;
                d1_next = 4'b0;
                d2_next = 4'b0;
            end
        else if (ms_tick)
            if (d0_reg != 9)
                d0_next = d0_reg + 1;
            else   // reach XX9
                begin
                    d0_next = 4'b0;
                    if (d1_reg != 9)
                        d1_next = d1_reg + 1;
                    else   // reach X99
                        begin
                            d1_next = 4'b0;
                            if (d2_reg != 9)
                                d2_next = d2_reg + 1;
                            else    // reach 999
                                d2_next = 4'b0;
                        end
                end
    end

    // output logic
    assign d0 = d0_reg;
    assign d1 = d1_reg;
    assign d2 = d2_reg;

endmodule
